package admin

import (
	"github.com/gin-gonic/gin"
	"gorm.io/gorm"
	"myai/core"
	"myai/core/types"
	"myai/handler"
	"myai/store/model"
	"myai/store/model/req"
	"myai/store/vo"
	"myai/utils"
	"myai/utils/resp"
)

type ChatModelHandler struct {
	handler.BaseHandler
}

func NewChatModelHandler(app *core.AppServer, db *gorm.DB) *ChatModelHandler {
	return &ChatModelHandler{BaseHandler: handler.BaseHandler{App: app, DB: db}}
}

// SaveOrUpdate godoc
// @Summary      更新或者新增模型
// @Description  更新或者新增模型
// @Tags         后台管理-模型管理
// @Accept       json
// @Produce      json
// @Param        req   body     req.ChatModelSaveReq  true  "模型信息"
// @Success      200  {object}  types.BizVo{data=vo.ChatModel}
// @Router       /api/admin/model/save_or_update [post]
// @Security AdminApiKeyAuth
func (h *ChatModelHandler) SaveOrUpdate(c *gin.Context) {
	var data req.ChatModelSaveReq
	if err := c.ShouldBindJSON(&data); err != nil {
		resp.ERROR(c, types.InvalidArgs)
		return
	}
	item := model.ChatModel{}
	// 更新
	if data.Id > 0 {
		h.DB.Where("id", data.Id).First(&item)
	}
	item.Name = data.Name
	item.Value = data.Value
	item.Enabled = data.Enabled
	item.SortNum = data.SortNum
	item.Open = data.Open
	item.Power = data.Power
	item.MaxTokens = data.MaxTokens
	item.MaxContext = data.MaxContext
	item.Temperature = data.Temperature
	item.KeyId = data.KeyId
	item.Type = data.Type
	var res *gorm.DB
	if data.Id > 0 {
		// 更新
		res = h.DB.Save(&item)
	} else {
		// 新增
		res = h.DB.Create(&item)
	}
	if res.Error != nil {
		log.Errorf("操作数据库出错：%v", res.Error)
		resp.ERROR(c, "操作数据库出错："+res.Error.Error())
		return
	}

	var itemVo vo.ChatModel
	err := utils.CopyObject(item, &itemVo)
	if err != nil {
		resp.ERROR(c, "数据拷贝出错："+err.Error())
		return
	}
	itemVo.Id = item.Id
	itemVo.CreatedAt = item.CreatedAt.Unix()
	resp.SUCCESS(c, itemVo)
}

// List godoc
// @Summary      模型列表
// @Description  模型列表
// @Tags         后台管理-模型管理
// @Accept       json
// @Produce      json
// @Param        enable   query     bool  false  "是否启用"
// @Param        name     query     string  false  "模型名称"
// @Success      200  {object}  types.BizVo{data=[]vo.ChatModel}
// @Router       /api/admin/model/list [get]
// @Security AdminApiKeyAuth
func (h *ChatModelHandler) List(c *gin.Context) {
	session := h.DB.Session(&gorm.Session{})
	enable := h.GetBool(c, "enable")
	name := h.GetTrim(c, "name")
	if enable {
		session = session.Where("enabled", enable)
	}
	if name != "" {
		session = session.Where("name LIKE ?", name+"%")
	}
	var items []model.ChatModel
	var cms = make([]vo.ChatModel, 0)
	res := session.Order("sort_num ASC").Find(&items)
	if res.Error != nil {
		resp.ERROR(c, "查询数据库出错："+res.Error.Error())
		return
	}

	// 获取 API KEY id集合
	keyIds := make([]int, 0)
	for _, v := range items {
		keyIds = append(keyIds, v.KeyId)
	}
	// 查询 API KEY
	var keys []model.ApiKey
	keyMap := make(map[uint]string)
	h.DB.Where("id IN ?", keyIds).Find(&keys)
	for _, v := range keys {
		keyMap[v.Id] = v.Name
	}

	for _, item := range items {
		var cm vo.ChatModel
		err := utils.CopyObject(item, &cm)
		if err == nil {
			cm.Id = item.Id
			cm.CreatedAt = item.CreatedAt.Unix()
			cm.UpdatedAt = item.UpdatedAt.Unix()
			cm.KeyName = keyMap[uint(item.KeyId)]
			cms = append(cms, cm)
		} else {
			log.Errorf("拷贝模型数据出错：%v", err)
		}
	}
	resp.SUCCESS(c, cms)
}

// Set godoc
// @Summary      修改指定字段的值
// @Description  修改指定字段的值
// @Tags         后台管理-模型管理
// @Accept       json
// @Produce      json
// @Param        req   body     req.ChatModelUpdateFiledReq  true  "修改指定字段的值"
// @Success      200  {object}  types.BizVo{}
// @Router       /api/admin/model/set [post]
// @Security AdminApiKeyAuth
func (h *ChatModelHandler) Set(c *gin.Context) {
	var data req.ChatModelUpdateFiledReq
	if err := c.ShouldBindJSON(&data); err != nil {
		resp.ERROR(c, types.InvalidArgs)
		return
	}
	err := h.DB.Model(&model.ChatModel{}).Where("id = ?", data.Id).Update(data.Filed, data.Value).Error
	if err != nil {
		resp.ERROR(c, "操作数据库失败："+err.Error())
		return
	}
	resp.SUCCESS(c)
}

// Sort godoc
// @Summary      修改模型数据排序
// @Description  修改模型数据排序
// @Tags         后台管理-模型管理
// @Accept       json
// @Produce      json
// @Param        req   body     req.ChatModelUpdateSortReq  true  "修改模型排序"
// @Success      200  {object}  types.BizVo{}
// @Router       /api/admin/model/sort [post]
// @Security AdminApiKeyAuth
func (h *ChatModelHandler) Sort(c *gin.Context) {
	var data req.ChatModelUpdateSortReq
	if err := c.ShouldBindJSON(&data); err != nil {
		resp.ERROR(c, types.InvalidArgs)
		return
	}
	for index, id := range data.Ids {
		err := h.DB.Model(&model.ChatModel{}).Where("id = ?", id).Update("sort_num", data.Sorts[index]).Error
		if err != nil {
			resp.ERROR(c, "修改模型排序出错："+err.Error())
			return
		}
	}
	resp.SUCCESS(c)
}

// Remove godoc
// @Summary      根据Id删除对应的模型数据
// @Description  根据Id删除对应的模型数据
// @Tags         后台管理-模型管理
// @Accept       json
// @Produce      json
// @Param        id   query     int  true  "模型Id"
// @Success      200  {object}  types.BizVo{}
// @Router       /api/admin/model/remove [get]
// @Security AdminApiKeyAuth
func (h *ChatModelHandler) Remove(c *gin.Context) {
	id := h.GetInt(c, "id", 0)
	if id <= 0 {
		resp.ERROR(c, types.InvalidArgs)
		return
	}
	err := h.DB.Where("id = ?", id).Delete(&model.ChatModel{}).Error
	if err != nil {
		resp.ERROR(c, "删除模型时数据库出错："+err.Error())
		return
	}
	resp.SUCCESS(c)
}
